#include "stdafx.h"
/*
    The goals of the simulation are as follow
    - Births per couple must not exceed 2.5, so 1.25 per person.
    - only 1 birth per year
    - only people between 20 and 35 can have children

    we loop the population
    if the person is between 20 and 35, we add one children
*/
void demograph_list :: init()
{
    bar_ratio = 1.f;
    cout << "bar_ratio " << bar_ratio << endl;
    deaths_total = 0;
    births_total = 0;
    starting_population = pop_total = AGE_MAX;

    pop_max = POP_MAX;

    run_sim = true;

    FOR2(0, AGE_REPRODUCE_MIN)                  add_indiv(i, 0);
    FOR2(AGE_REPRODUCE_MIN, AGE_REPRODUCE_MAX)  add_indiv(i, 1);
    FOR2(AGE_REPRODUCE_MAX, AGE_MAX)            add_indiv(i, 0);
}
bool dies_of_old_age(const indiv & ind) { return ind.age + 1 > AGE_MAX; }
void demograph_list :: add_indiv(uchar age, uchar kids)
{
    indiv ind;
    ind.age = age;
    ind.kids = kids;
    pop.push_back(ind);
}
void demograph_list :: simulation_step() // equivalent to 1 year
{
    births_this_year =
    reproducing_people =
    deaths_this_year =
    gen_heirs = 0;

    pop.remove_if(dies_of_old_age);
    for(auto ind = pop.begin(); ind != pop.end(); ++ ind)
    {
        ind->age ++; 
        if(ind->age >= AGE_REPRODUCE_MIN
            && ind->age < AGE_REPRODUCE_MAX)
        {
            gen_heirs += ind->kids;
            reproducing_people++;
        }
    }

    for(auto ind = pop.begin(); ind != pop.end(); ++ ind)
    {
        if(float(ind->kids) > CHILD_PER_PERSON)
            continue;
        if(pop.size() < pop_max)
        {
            if(float(gen_heirs) / float(reproducing_people) > CHILD_PER_PERSON)
                return;

            births_total++;
            births_this_year++;
            ind->kids++;
            gen_heirs++; // this is important !

            add_indiv(0,0);
        }
        else
        {
            cout << "too many people\n";
            run_sim = false;
            return;
        }
    }
}
void demograph_list :: init_bars()
{
    text = sf::Text("",sf::Font::getDefaultFont(),FONT_SIZE);
    text.setPosition(30,0);
    FOR(AGE_MAX)
        bars[i].setPosition(BAR_WIDTH*i, BAR_H_MAX);
        //bars[i].setSize(Vector2f(float(BAR_WIDTH), float(BAR_H_MAX)));

    FOR2(0, AGE_REPRODUCE_MIN)                  bars[i].setFillColor(sf::Color(128,0,0));//::Cyan);
    FOR2(AGE_REPRODUCE_MIN, AGE_REPRODUCE_MAX)  bars[i].setFillColor(sf::Color(0,128,0));//::Green);
    FOR2(AGE_REPRODUCE_MAX,AGE_MAX)             bars[i].setFillColor(sf::Color(0,0,128));//::Yellow);
}
void demograph_list :: update_bars()
{
    FOR(AGE_MAX) age_group[i] = 0;
    FORLIST      
        age_group[ind->age]++;
    FOR(AGE_MAX)
        while(float(age_group[i])*bar_ratio * float(BAR_H_MAX) > float(BAR_H_MAX))
            bar_ratio *= 0.5f;
    ostringstream oss;

    FOR(AGE_MAX)
        bars[i].setSize(
            sf::Vector2f(BAR_WIDTH,
                - float(BAR_H_MAX) * bar_ratio * float(age_group[i])
                ));

    oss
         << "\n bar_ratio: "      << bar_ratio
         << "\n born per year: "  << births_this_year
         << "\n able people: "    << reproducing_people
         << "\n inhabitants: "    << pop.size()
         << "\n births total: "   << births_total << "\n";
    text.setString(oss.str());
}